/**
 * Software License, Version 1.0
 * 
 * Copyright 2003 The Trustees of Indiana University.  All rights reserved.
 * 
 *
 *Redistribution and use in source and binary forms, with or without 
 *modification, are permitted provided that the following conditions are met:
 *
 *1) All redistributions of source code must retain the above copyright notice,
 * the list of authors in the original source code, this list of conditions and
 * the disclaimer listed in this license;
 *2) All redistributions in binary form must reproduce the above copyright 
 * notice, this list of conditions and the disclaimer listed in this license in
 * the documentation and/or other materials provided with the distribution;
 *3) Any documentation included with all redistributions must include the 
 * following acknowledgement:
 *
 *"This product includes software developed by the Community Grids Lab. For 
 * further information contact the Community Grids Lab at 
 * http://communitygrids.iu.edu/."
 *
 * Alternatively, this acknowledgement may appear in the software itself, and 
 * wherever such third-party acknowledgments normally appear.
 * 
 *4) The name Indiana University or Community Grids Lab or NaradaBrokering, 
 * shall not be used to endorse or promote products derived from this software 
 * without prior written permission from Indiana University.  For written 
 * permission, please contact the Advanced Research and Technology Institute 
 * ("ARTI") at 351 West 10th Street, Indianapolis, Indiana 46202.
 *5) Products derived from this software may not be called NaradaBrokering, 
 * nor may Indiana University or Community Grids Lab or NaradaBrokering appear
 * in their name, without prior written permission of ARTI.
 * 
 *
 * Indiana University provides no reassurances that the source code provided 
 * does not infringe the patent or any other intellectual property rights of 
 * any other entity.  Indiana University disclaims any liability to any 
 * recipient for claims brought by any other entity based on infringement of 
 * intellectual property rights or otherwise.  
 *
 *LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH NO 
 *WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA UNIVERSITY GIVES
 *NO WARRANTIES AND MAKES NO REPRESENTATION THAT SOFTWARE IS FREE OF 
 *INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR OTHER PROPRIETARY RIGHTS. 
 *INDIANA UNIVERSITY MAKES NO WARRANTIES THAT SOFTWARE IS FREE FROM "BUGS", 
 *"VIRUSES", "TROJAN HORSES", "TRAP DOORS", "WORMS", OR OTHER HARMFUL CODE.  
 *LICENSEE ASSUMES THE ENTIRE RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR 
 *ASSOCIATED MATERIALS, AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION 
 *GENERATED USING SOFTWARE.
 */
package cgl.narada.util;

import java.net.InetAddress;
import java.util.Iterator;
import java.util.Properties;

import cgl.narada.util.logging.Logger;
import cgl.narada.util.logging.LoggerFactory;

/**
 * A help class to get properties needed to conduct transport
 * test. Properties will be written in a properties file and
 * this class can read them out. There are only two end nodes
 * involved in transport test currently; but the idea is that
 * all tests will take only one command line argument -- path
 * to the properties file.
 * 
 * @author Hongbin Liu
 * @version 1.0
 */
public class PropertiesHelp {
    
    final static Logger log =
	LoggerFactory.getLogger(PropertiesHelp.class.getName());

    protected Configuration config;
    private String propFile = "transportTest.properties";
    private String[] keys;
    private String[] initiatorKeys;
    private String[] acceptorKeys;
    private String myKey;
    private String transport;
    private boolean isInitiator;

    public PropertiesHelp(String fname, String transport) {
	this.transport = transport;

	try {
	    if (fname != null && !fname.equals("")) {
		config = 
		    new 
		    ConfigurationParamsReader(fname);
	    }
	    else {
		config =
		    new
		    ConfigurationParamsReader(propFile);
	    }
	    keys = config.getStringArray("keys");
	    initiatorKeys = config.getStringArray("initiator");	
	    acceptorKeys = config.getStringArray("acceptor");		    
	    myKey = findMyKey(keys);
	    isInitiator();
	    //System.out.println("mykey:"+myKey);

	} catch (Exception e) { 
	    log.warn(e.getMessage());
	    if (config == null) {
		System.exit(1);
	    }
	}

    }

    /**
     * @param String[] keys. A, B, C, ...
     * @return String. Either A, B, C, ... that corresponds to this host
     */
    private String findMyKey(String[] keys) {
	String key = null;
	String localHost = localHost();

	Configuration conf = config.subset("host");
        for (Iterator it = conf.getKeys(); it.hasNext();) {
	    key = (String) it.next();
	    for(int i=0; i<keys.length; i++) {
		if (key.equals(keys[i])) {
		    if(conf.getString(key).equals(localHost)) return key;
		}
	    }
	}
	return "";
    }

    public String localHost() {
	String host = null;
	try {
	    host = InetAddress.getLocalHost().getHostName();
	    //System.out.println("host:"+host);
	} catch (Exception e) { log.error(e.getMessage()); }
	return host;
    }

    public boolean isInitiator() {
	for(int i=0; i<initiatorKeys.length; i++) {
	    //System.out.println("initiatorKey:"+initiatorKeys[i]);
	    if (myKey.equals(initiatorKeys[i])) {
		this.isInitiator = true;
		return true;
	    }
	}
	this.isInitiator = false;
	return false;
    }

    public String acceptorHost() {
	String key = config.getString("acceptor."+myKey);
	return config.getString("host."+key);
    }

    public String acceptorHTTPPort() {
	System.out.println("myKey="+myKey);
	if (this.isInitiator) {
	    String key = config.getString("acceptor."+myKey);	    
	    String port = config.getString("http.port."+key);
	    System.out.println("key="+key+", port="+port);
	    return port;
	} else {
	    return config.getString("http.port."+myKey);
	}
    }

    public String acceptorSSLPort() {
	if (this.isInitiator) {
	    String key = config.getString("acceptor."+myKey);
	    String port = config.getString("ssl.port."+key);
	    return port;
	} else {
	    return config.getString("ssl.port."+myKey);
	}
    }

    public String userName() {
	return config.getString("user.name."+myKey);
    }

    public String userPass() {
	return config.getString("user.password."+myKey);
    }

    public String proxyHost() {
	return config.getString("proxy.host."+myKey);
    }

    public String proxyPort() {
	return config.getString("proxy.port."+myKey);
    }
    
    public long httpStatus() {
	return config.getLong("http.status."+myKey);
    }
     public String keyStore() {
        return config.getString("keyStore."+myKey);
    }

    public String keyStorePass() {
        return config.getString("keyStorePassword."+myKey);
    }

    public String trustStore() {
        return config.getString("trustStore."+myKey);
    }

    public String trustStorePass() {
        return config.getString("trustStorePassword."+myKey);
    }		

    public Properties addProperties(Properties prop) {
	String proxyHost, proxyPort, user, password, host, port, localhost;
	String keyStore, keyPass, trustStore, trustPass;

	if (this.isInitiator) {
	    if (( proxyHost = proxyHost()) != null) {
		prop.put("https.proxyHost", proxyHost);
		//System.out.println("proxy host "+proxyHost);
	    }
	    if (( proxyPort = proxyPort()) != null)
		prop.put("https.proxyPort", proxyPort);
	    if (( user = userName()) != null)
		prop.put("username",user);
	    if (( password = userPass()) != null)
	    prop.put("password",password);
	    if (( host = acceptorHost()) != null)
	    prop.put("hostname", host);
	    if(transport.equals("http")) {
		if (( port = acceptorHTTPPort()) != null) {
		    prop.put("portnum", port);
		    prop.put("acceptor.http.port", port);
		}
	    }
	    if(transport.equals("ssl")) {
		if (( port = acceptorSSLPort()) != null) {
		    prop.put("portnum", port);
		    prop.put("acceptor.ssl.port", port);
		}
		if ((keyStore=keyStore()) != null)
		    prop.put("acceptor.keyStore",keyStore);
		if ((keyPass=keyStorePass()) != null)
		    prop.put("acceptor.keyStorePassword", keyPass);
		if ((trustStore=trustStore()) != null)
		    prop.put("initiator.trustStore", trustStore);
		if ((trustPass=trustStorePass()) != null)
		    prop.put("initiator.trustStorePassword", trustPass);
	    }
	}

	if ((localhost = localHost()) != null) {
	    prop.put("localhost", localhost);
	}

	log.info("local host: " + localHost());

	return prop;
    }
}
